package org.harsh.common;

import cn.hutool.core.codec.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;

public class Util {
    public static byte[] long2Bytes(long value) {
        byte[] buffer = new byte[8];
        for(int i = 0; i<8;i++) {
            int offset = 64-(i+1)*8;
            buffer[i] = (byte)((value >> offset) & 0xff);
        }
        return buffer;
    }

    public static long bytes2Long(byte[] value){
        return bytes2Long(value, 0);
    }

    public static long bytes2Long(byte[] value, int offset){
        ByteBuffer buffer = ByteBuffer.wrap(value, offset,8);
        return buffer.getLong();
    }



    public static byte[] short2bytes(short s){
        byte[] b = new byte[2];
        for(int i = 0; i < 2; i++){
            int offset = 16 - (i+1)*8; //因为byte占4个字节，所以要计算偏移量
            b[i] = (byte)((s >> offset)&0xff); //把16位分为2个8位进行分别存储
        }
        return b;
    }

    public static short bytes2short(byte[] b){
        return bytes2short(b, 0);
    }


    public static short bytes2short(byte[] b, int offset){
        short l = 0;
        for (int i = offset; i < offset + 2; i++) {
            l<<=8; //<<=和我们的 +=是一样的，意思就是 l = l << 8
            l |= (b[i] & 0xff); //和上面也是一样的  l = l | (b[i]&0xff)
        }
        return l;
    }

    public static byte[] int2bytes(int s){
        byte[] b = new byte[2];
        for(int i = 0; i < 4; i++){
            int offset = 16 - (i+1)*8;
            b[i] = (byte)((s >> offset)&0xff);
        }
        return b;
    }


    public static int bytes2int(byte[] b){
        return bytes2int(b, 0);
    }

    public static int bytes2int(byte[] b, int offset){
        int l = 0;
        for (int i = offset; i < offset + 4; i++) {
            l<<=8; //<<=和我们的 +=是一样的，意思就是 l = l << 8
            l |= (b[i] & 0xff); //和上面也是一样的  l = l | (b[i]&0xff)
        }
        return l;
    }


    /**
     * 将address转换为base64，并放入Map
     * @param address
     * @return
     */
    public static String socketAddrToStr(InetSocketAddress address){
        String ip = address.getAddress().getHostAddress();
        int port = address.getPort();
        String str = ip + "_" + port;
        return Base64.encode(str.getBytes(Config.DEFAULT_CHARSET));
    }

    private static final java.util.Base64.Decoder DECODER_64 = java.util.Base64.getDecoder();
    private static final java.util.Base64.Encoder ENCODER_64 = java.util.Base64.getEncoder();

    // 获取MD5
    public static byte[] fileMD5 (String filePath) throws IOException {
        return DigestUtils.md5(new FileInputStream(filePath));
    }

    public static byte[] fileMD5 (File file) throws IOException {
        return DigestUtils.md5(new FileInputStream(file));
    }

    public static String fileMD5Str (File file) throws IOException {
        return Base64.encode(DigestUtils.md5(new FileInputStream(file)));
    }

    public static byte[] byteArrMD5 (byte[] bytearr) throws IOException {
        return DigestUtils.md5(bytearr);
    }

    @Deprecated
    public static String fileMD5HexStr (String filePath) throws IOException {
        return DigestUtils.md5Hex(new FileInputStream(filePath));
    }
    @Deprecated
    public static String fileMD5Str (String filePath) throws IOException {
        return new String(DigestUtils.md5(new FileInputStream(filePath)), Config.DEFAULT_CHARSET);
    }
    @Deprecated
    public static String fileMD5Hex(File file) throws IOException {
        return DigestUtils.md5Hex(new FileInputStream(file));
    }
    @Deprecated
    public static String byteArrMD5HexStr (byte[] bytearr) throws IOException {
        return DigestUtils.md5Hex(bytearr);
    }

    // 切换为Base64编码，长度为16位
    public static String byteArrMD5Str (byte[] bytearr) throws IOException {
        return Base64.encode(byteArrMD5(bytearr));
        //return new String(byteArrMD5(bytearr), Config.DEFAULT_CHARSET);
    }

    // base64 encode implement byte arr to str
    public static String base64Encode(byte[] data) {
        return ENCODER_64.encodeToString(data);
    }

    // base64 decode implement str to byte arr
    public static byte[] base64Decode(String data) {
        return DECODER_64.decode(data);
    }

}
